package com.ehsunbehravesh.mypasswords.io;

import com.ehsunbehravesh.mypasswords.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Observable;
import javax.activation.MimetypesFileTypeMap;

public class FileLoader extends Observable implements Runnable {
  // <editor-fold defaultstate="collapsed" desc="FIELDS">  

  private int bufferSize;
  private File file;
  private FileInputStream fileInputStream;
  private InputStreamReader inputStreamReader;
  private Byte[] content;
  private String filename;
  private String mimeType;
  private long size;
  private Charset charset;
  // </editor-fold>

  // <editor-fold defaultstate="collapsed" desc="CONSTRUCTORS & DESTRUCTORS">
  public FileLoader(File file, int bufferSize) {
    super();
    this.file = file;
    this.bufferSize = bufferSize;
  }

  @Override
  protected void finalize() throws Throwable {
    if (fileInputStream != null) {
      fileInputStream.close();
    }
    if (inputStreamReader != null) {
      inputStreamReader.close();
    }
    super.finalize();
  }
  // </editor-fold>

  public void run() {
    try {
      filename = file.getName();
      size = file.length();
      MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
      mimeType = fileTypeMap.getContentType(file);

      fileInputStream = new FileInputStream(file);
      inputStreamReader = new InputStreamReader(fileInputStream);
      charset = Charset.forName(inputStreamReader.getEncoding());
      byte[] buffer = new byte[bufferSize];
      ArrayList<Byte> contentOfFile = new ArrayList<Byte>();

      int readBytes = -1;
      while ((readBytes = fileInputStream.read(buffer)) != -1) {
        byte[] realData = new byte[readBytes];
        System.arraycopy(buffer, 0, realData, 0, realData.length);

        for (int i = 0; i < realData.length; i++) {
          byte b = realData[i];
          contentOfFile.add(b);
        }

        buffer = new byte[bufferSize];
        setChanged();
        notifyObservers(new FileLoaderMessage(FileLoaderMessage.PROGRESS));
        Thread.sleep(1);
      }

      content = new Byte[contentOfFile.size()];
      content = contentOfFile.toArray(content);
      setChanged();
      notifyObservers(new FileLoaderMessage(FileLoaderMessage.FINISHED, "loading file finished."));
    } catch (Exception ex) {
      setChanged();
      notifyObservers(new FileLoaderMessage(FileLoaderMessage.EXCEPTION, "Error in reading file! " + ex.getMessage()));
      Logger.log(ex.getMessage());
    } finally {
      if (fileInputStream != null) {
        try {
          fileInputStream.close();
        } catch (IOException ex) {
          Logger.log(ex.getMessage());
        }
      }
      if (inputStreamReader != null) {
        try {
          inputStreamReader.close();
        } catch (IOException ex) {
          Logger.log(ex.getMessage());
        }
      }
    }
  }

  public Byte[] getContent() {
    return content;
  }

  public Charset getCharset() {
    return charset;
  }

  public String getFilename() {
    return filename;
  }

  public String getMimeType() {
    return mimeType;
  }

  public long getSize() {
    return size;
  }
}
